﻿// CMDraw_Dlg.cpp: 实现文件
//

#include "pch.h"
#include "MFC_DRAW.h"
#include "DlgDrawGeometry.h"
#include "afxdialogex.h"
#include "Resource.h"
#include <string>
#include <sstream>
#include <fstream>

#include <afxwin.h>
#import "msxml6.dll"
using namespace std;



// CMDraw_Dlg 对话框

IMPLEMENT_DYNAMIC(DlgDrawGeometry, CDialogEx)

DlgDrawGeometry::DlgDrawGeometry(CWnd* pParent /*=nullptr*/)
    : CDialogEx(IDD_FIGURE_DLG, pParent)
{
    m_mousel_isdown = false;
}

DlgDrawGeometry::~DlgDrawGeometry()
{
}

void DlgDrawGeometry::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_LIST1, m_list1);
    DDX_Control(pDX, IDC_DRAW_BOARD, m_draw_board);
    DDX_Control(pDX, IDC_FIGURE_TREE, m_figure_tree);
    DDX_Text(pDX, IDC_EDIT_DEGREE, m_nDegree);
}


BEGIN_MESSAGE_MAP(DlgDrawGeometry, CDialogEx)
    ON_LBN_SELCHANGE(IDC_LIST1, &DlgDrawGeometry::OnSelchangeList1)
    ON_LBN_DBLCLK(IDC_LIST1, &DlgDrawGeometry::OnDblclkList1)
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_LBUTTONDBLCLK()
    ON_BN_CLICKED(IDC_BUTTON1, &DlgDrawGeometry::OnBnClickedStraightLine)
    ON_WM_MOUSEMOVE()
    ON_BN_CLICKED(IDC_BUTTON_DRAW_BSPLINE, &DlgDrawGeometry::OnBnClickedBSpline)
    ON_BN_CLICKED(IDC_BUTTON_CLEAR, &DlgDrawGeometry::OnBnClickedButtonClear)
END_MESSAGE_MAP()


// CMDraw_Dlg 消息处理程序
void DlgDrawGeometry::OnSelchangeList1()
{
    int i = m_list1.GetCurSel();//获取当前项
    CString str;
    m_list1.GetText(i, str);

    //---在图片框显示选择项
    CDC* pdc = m_draw_board.GetDC();
    CRect draw_board_client;
    m_draw_board.GetClientRect(draw_board_client);
    pdc->DrawText(str, draw_board_client, DT_SINGLELINE || DT_VCENTER || DT_CENTER);
}

void DlgDrawGeometry::OnDblclkList1()
{
    int i = m_list1.GetCurSel();//获取当前项

    //---在图片框显示选择项
    CString str;
    CDC* pdc = m_draw_board.GetDC();
    CRect draw_board_client;
    m_draw_board.GetClientRect(draw_board_client);

    //删除选中行
    m_list1.DeleteString(i);
    str.Format(_T("                    "));
    pdc->DrawText(str, draw_board_client, DT_SINGLELINE || DT_VCENTER || DT_CENTER);
}

void DlgDrawGeometry::Listbox_Practice()
{
    m_list1.ResetContent();//清空全部数据
    CString str;
    for(int i = 0; i < 10; ++i)
    {
        str.Format(_T("Item：%d"), i);
        m_list1.AddString(str);
    }
    m_list1.SetCurSel(5);
}

void DlgDrawGeometry::OnLButtonDown(UINT nFlags, CPoint point)
{
    m_mousel_down.x = point.x - m_correct_value.x;
    m_mousel_down.y = point.y - m_correct_value.y;
    m_mousel_isdown = true;

    if(m_BSplineButtonIsDown)
    {
        m_vecBSplineInsertPoint.push_back(m_mousel_down);
        DrawBSpline();
    }
    CDialogEx::OnLButtonDown(nFlags, point);
}

void DlgDrawGeometry::OnLButtonUp(UINT nFlags, CPoint point)
{
    m_mousel_isdown = false;
    CDialogEx::OnLButtonUp(nFlags, point);
}

void DlgDrawGeometry::OnLButtonDblClk(UINT nFlags, CPoint point)
{
    CDialogEx::OnLButtonDblClk(nFlags, point);
}

void DlgDrawGeometry::OnMouseMove(UINT nFlags, CPoint point)
{
    if(m_BSplineButtonIsDown)
    {
        CDialogEx::OnMouseMove(nFlags, point);
        return;
    }

    m_mouse_move.x = point.x - m_correct_value.x;
    m_mouse_move.y = point.y - m_correct_value.y;
    if(m_mousel_isdown)
    {
        Draw_Figure();
    }

    CDialogEx::OnMouseMove(nFlags, point);
}

void DlgDrawGeometry::OnBnClickedStraightLine()
{
    m_BSplineButtonIsDown = false;
    m_vecBSplineInsertPoint.clear();
    m_vecBSplinePoint.clear();
    m_draw_number = -1;
    Initial_Tree();
    Write_XML();
    Creat_Figure_From_XML();
}

void DlgDrawGeometry::OnBnClickedBSpline()
{
    Get_Correct_Value();
    m_BSplineButtonIsDown = true;
    DrawBSpline();
}

void DlgDrawGeometry::OnBnClickedButtonClear()
{
    m_vecBSplineInsertPoint.clear();
    m_vecBSplinePoint.clear();
    m_draw_number = -1;
    DrawBSpline();
}


//------函数------
//---绘制B样条曲线
void DlgDrawGeometry::DrawBSpline()
{
    UpdateData();
    int nBSplinePoitNum = 5 * (int)m_vecBSplineInsertPoint.size();
    m_vecBSplineControlPoint.resize(0);
    m_vecBSplinePoint.resize(0);

    GetBSplinePoint(m_vecBSplineInsertPoint, m_vecBSplineControlPoint,
                    m_vecBSplinePoint, nBSplinePoitNum, m_nDegree);

    CDC* pDC = m_draw_board.GetDC();
    CPen    penLine(PS_SOLID, 2, RGB(255, 0, 255));
    CBrush  brushBackeground(RGB(255, 255, 255));
    CBrush  brushInsertPoint(RGB(0, 255, 10));
    CBrush  brushControlPoint(RGB(255, 200, 0));
    CDC memDC;
    CBitmap memBitmap;
    memDC.CreateCompatibleDC(pDC);
    memBitmap.CreateCompatibleBitmap(pDC, m_draw_board_client.Width(), m_draw_board_client.Height());
    memDC.SelectObject(&memBitmap);   //将位图选进内存中
    memDC.FillRect(m_draw_board_client, &brushBackeground);

    double dRectSize = 6;

    for(int i = 0; i < (int)m_vecBSplinePoint.size() - 1; ++i)
    {//---画B样条曲线
        CPen* pPenLine = memDC.SelectObject(&penLine);
        memDC.MoveTo(m_vecBSplinePoint[i]);
        memDC.LineTo(m_vecBSplinePoint[i + 1]);
        memDC.SelectObject(pPenLine);
    }

    for(int i = 0; i < (int)m_vecBSplineInsertPoint.size(); ++i)
    {//---画插值点
        double x = m_vecBSplineInsertPoint[i].x;
        double y = m_vecBSplineInsertPoint[i].y;
        CRect rect(x - dRectSize, y - dRectSize, x + dRectSize, y + dRectSize);
        memDC.FillRect(rect, &brushInsertPoint);
    }

    for(int i = 0; i < (int)m_vecBSplineControlPoint.size(); ++i)
    {//---画控制点
        double x = m_vecBSplineControlPoint[i].x;
        double y = m_vecBSplineControlPoint[i].y;
        CRect rect(x - dRectSize, y - dRectSize, x + dRectSize, y + dRectSize);
        memDC.FillRect(rect, &brushControlPoint);
    }

    CString str;
    str.Format(_T("插入点：%d；控制点：%d"), (int)m_vecBSplineInsertPoint.size(), m_vecBSplineControlPoint.size());
    memDC.DrawText(str, m_draw_board_client, DT_SINGLELINE || DT_VCENTER || DT_CENTER);
    pDC->BitBlt(m_draw_board_client.left, m_draw_board_client.top, m_draw_board_client.Width(), m_draw_board_client.Height(), &memDC, 0, 0, SRCCOPY);
}

//---更新m_nDegree
void DlgDrawGeometry::UpdateDegree()
{
    UpdateData(TRUE);
    if(m_nDegree < 1)
    {
        m_nDegree = 1;
        UpdateData(FALSE);
    }
}

//---获取坐标修正值
void DlgDrawGeometry::Get_Correct_Value()
{
    CDC* pdc = m_draw_board.GetDC();
    m_draw_board.GetClientRect(m_draw_board_client);
    m_draw_board.GetWindowRect(m_draw_board_window);

    CRect dlg_client;
    CRect dlg_window;
    GetWindowRect(dlg_window);
    GetClientRect(dlg_client);
    m_correct_value.x = (m_draw_board_window.left - dlg_window.left - 4);
    m_correct_value.y = (m_draw_board_window.top - dlg_window.top - (m_draw_board_client.top - dlg_client.top) + 4);
}

//---绘制图形
void DlgDrawGeometry::Draw_Figure()
{
    CDC* pdc = m_draw_board.GetDC();
    CBrush brush(RGB(255, 255, 255));
    CDC memdc;
    CBitmap mem_bitmap;
    memdc.CreateCompatibleDC(pdc);
    mem_bitmap.CreateCompatibleBitmap(pdc, m_draw_board_client.Width(), m_draw_board_client.Height());
    memdc.SelectObject(&mem_bitmap);   //将位图选进内存中
    memdc.FillRect(m_draw_board_client, &brush);

    memdc.MoveTo(m_mousel_down);
    memdc.LineTo(m_mouse_move);
    m_draw_number++;
    CString str;
    str.Format(_T("数量：%d"), m_draw_number);
    memdc.DrawText(str, m_draw_board_client, DT_SINGLELINE || DT_VCENTER || DT_CENTER);

    pdc->BitBlt(m_draw_board_client.left, m_draw_board_client.top, m_draw_board_client.Width(), m_draw_board_client.Height(), &memdc, 0, 0, SRCCOPY);
}

//---初始画树控件
void DlgDrawGeometry::Initial_Tree()
{
    m_figure_tree.DeleteAllItems();
    CImageList imagelist;
    imagelist.Create(32, 32, ILC_COLOR32, 6, 6);
    CBitmap    bitmap;
    bitmap.LoadBitmap(IDB_BITMAP_STRAIGHT);
    imagelist.Add(&bitmap, RGB(255, 0, 0));
    m_figure_tree.SetImageList(&imagelist, TVSIL_NORMAL);

    HTREEITEM hroot;
    HTREEITEM hstraight;
    HTREEITEM hcircle;
    HTREEITEM htriangle;

    hroot = m_figure_tree.InsertItem(_T("图形"), 0, 0, TVI_ROOT);
    hstraight = m_figure_tree.InsertItem(_T("直线"), 0, 0, hroot);
    hstraight = m_figure_tree.InsertItem(_T("straight：1"), hstraight);
    hcircle = m_figure_tree.InsertItem(_T("圆"), 0, 0, hroot);
    htriangle = m_figure_tree.InsertItem(_T("三角形"), 0, 0, hroot);
}

//---从xml文件创建图形
void DlgDrawGeometry::Creat_Figure_From_XML()
{
    using namespace MSXML2;

    MSXML2::IXMLDOMDocumentPtr xmlDoc;
    MSXML2::IXMLDOMElementPtr xmlRoot;
    MSXML2::IXMLDOMElementPtr parentNode;
    MSXML2::IXMLDOMElementPtr subNode;
    MSXML2::IXMLDOMNodeListPtr parentNodeLists;
    MSXML2::IXMLDOMNodeListPtr subNodeList;

    HRESULT hr = xmlDoc.CreateInstance(_uuidof(MSXML2::DOMDocument60));

    if(!SUCCEEDED(hr))
    {
        return;
    }
    auto isload = xmlDoc->load("figure.XML");
    if(!isload)
    {
        MessageBox(_T("load xml fail"));
        return;
    }

    MessageBox(_T("load xml succese"));

    xmlRoot = xmlDoc->GetdocumentElement();
    parentNodeLists = xmlRoot->GetchildNodes();
    long parentNodeCount = parentNodeLists->Getlength();

    for(long i = 0; i < parentNodeCount; ++i)
    {
        parentNode = parentNodeLists->Getitem(i);
        subNodeList = parentNode->GetchildNodes();


        //jug node by Attribute
        subNode = subNodeList->Getitem(0);
        auto sunNodeAttrib = subNode->getAttribute("type");
        if(sunNodeAttrib == (_variant_t)"1")
        {
            MessageBox(_T("find attribute \"type = 1\""));
        }
        auto type = subNode->Gettext();



        //find node by tag name = "point"
        auto pointsList = parentNode->getElementsByTagName("point");
        if(pointsList)
        {
            int nPointsNum = pointsList->Getlength();
            CString strTemp;
            strTemp.Format(_T("find %d \"point\" node "), nPointsNum);
            MessageBox(strTemp);
        }
        else
        {
            break;
        }


        //juge node by name
        subNode = pointsList->Getitem(0);
        auto subNodeName = subNode->GetnodeName();
        if(subNodeName == (_bstr_t)"point")
        {
            MessageBox(_T("sure   naeme of subNode0 = \"point\""));
        }

        auto pointText = subNode->Gettext();

        //转化xml信息未整数
        std::istringstream stream1;
        stream1.str((char*)type);
        int f_type;
        stream1 >> f_type;
        std::istringstream stream2;
        int a, b, c, d;
        stream2.str((char*)pointText);
        stream2 >> a >> b >> c >> d;
    }
}


void WriteXml(MSXML2::IXMLDOMDocumentPtr xml_doc)
{
    using namespace MSXML2;

    MSXML2::IXMLDOMElementPtr xml_root;
    MSXML2::IXMLDOMElementPtr figur_node;
    MSXML2::IXMLDOMElementPtr figure_ifo_node;

    xml_root = xml_doc->GetdocumentElement();

    CString strTemp = _T("type");
    figur_node = xml_doc->createElement("figure");
    figur_node->setAttribute((_bstr_t)strTemp, 1);
    xml_root->appendChild(figur_node);

    {
        figure_ifo_node = xml_doc->createElement("type");
        figure_ifo_node->Puttext("0");
        figur_node->appendChild(figure_ifo_node);
    }


    {
        figure_ifo_node = xml_doc->createElement("id");
        figure_ifo_node->Puttext("1");
        figur_node->appendChild(figure_ifo_node);
    }


    {
        figure_ifo_node = xml_doc->createElement("point");
        figure_ifo_node->Puttext("11 22 33 44");
        figur_node->appendChild(figure_ifo_node);
    }

    //xml_doc->save("Figure.XML");
}


//---写xml文件
void DlgDrawGeometry::Write_XML()
{
    using namespace MSXML2;

    MSXML2::IXMLDOMDocumentPtr xml_doc;
    MSXML2::IXMLDOMElementPtr xml_root;
    MSXML2::IXMLDOMElementPtr figur_node;
    MSXML2::IXMLDOMElementPtr figure_ifo_node;
    MSXML2::IXMLDOMProcessingInstructionPtr pProInstruction;

    HRESULT hr = xml_doc.CreateInstance(_uuidof(MSXML2::DOMDocument60));

    if(!SUCCEEDED(hr))
    {
        return;
    }


    pProInstruction = xml_doc->createProcessingInstruction((_bstr_t)"xml", (_bstr_t)"version=\"1.0\" encoding=\"unicode\"");
    xml_doc->appendChild(pProInstruction);

    xml_root = xml_doc->createElement("root");
    xml_doc->appendChild(xml_root);


    figur_node = xml_doc->createElement("figure");
    figur_node->setAttribute("figure", 1);
    xml_root->appendChild(figur_node);


    {
        CString strTemp;
        strTemp.Format(_T("type %d     %Id    %f      %If     %g 我的老腰"),
                       (int)5, (long)55555, (float)5.5, (double)6.601, (double)78.9000);

        figure_ifo_node = xml_doc->createElement("type");
        figure_ifo_node->setAttribute("type", 1);
        figure_ifo_node->Puttext((_bstr_t)strTemp);
        figur_node->appendChild(figure_ifo_node);
    }


    {
        CString strTemp;
        strTemp.Format(_T("%I64d"), LONG64(6666666666666));
        figure_ifo_node = xml_doc->createElement("id");
        figure_ifo_node->Puttext("1");
        figur_node->appendChild(figure_ifo_node);
    }


    {
        figure_ifo_node = xml_doc->createElement("point");
        figure_ifo_node->Puttext("11 22 33 44");
        figur_node->appendChild(figure_ifo_node);
    }

    for(int i = 0; i < 3; ++i)
    {
        WriteXml(xml_doc);
    }

    xml_doc->save("Figure.XML");
}
